home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib43 / mntlib / sozobon / ps.c < prev    next >
C/C++ Source or Header  |  1992-01-15  |  6KB  |  219 lines

  1. /*
  2.  * ps.c - a program to print MiNT process statuses
  3.  *
  4.  * Based on the original ps by Tony Reynolds, cctony@sgisci1.ocis.olemiss.edu,
  5.  * and updated by Eric Smith and Allan Pratt.
  6.  * For use with MiNT release 0.9.
  7.  * Compiles with my port of the MiNTlib to Sozobon 2.0, as well as the GCC.
  8.  *
  9.  * $Log: ps.c,v $
  10.  * Revision 0.9  1992/01/15  21:48:22  sozobon
  11.  * dpg's first version.
  12.  * Uses opendir rather than Fsfirst/next.
  13.  * Print owner information, rather than parent process id.
  14.  *
  15.  */
  16.  
  17. static char *proc =
  18. "$Id: ps.c,v 0.9 1992/01/15 21:48:22 sozobon Exp sozobon $";
  19.  
  20. #include <basepage.h>
  21. #include <dirent.h>
  22. #include <errno.h>
  23. #include <ioctl.h>
  24. #include <pwd.h>
  25. #include <stat.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <unistd.h>
  30.  
  31. #define PROCDIR "u:/proc"
  32.  
  33. #define ulong unsigned long
  34. #define ushort unsigned short
  35.  
  36. extern int __mint;
  37.  
  38. /* The following structures are taken from proc.h in the MiNT kernel. */
  39.  
  40. /* a process context consists, for now, of its registers */
  41.  
  42. typedef struct _context {
  43.     long    regs[15];    /* registers d0-d7, a0-a6 */
  44.     long    usp;        /* user stack pointer (a7) */
  45.     short    sr;        /* status register */
  46.     long    pc;        /* program counter */
  47.     long    ssp;        /* supervisor stack pointer */
  48.     long    term_vec;    /* GEMDOS terminate vector (0x102) */
  49.     char    fstate[216];    /* FPU internal state */
  50.     char    fregs[12*8];    /* registers fp0-fp7 */
  51.     long    fctrl[3];        /* FPCR/FPSR/FPIAR */
  52.     short    sfmt;            /* stack frame format identifier */
  53.     long    iar;            /* instruction address */
  54.     short    internal[4];    /* four words of internal info */
  55. } CONTEXT;
  56.  
  57. #define PROC_CTXTS    2
  58.  
  59. typedef struct proc {
  60. /* this is stuff that the public can know about */
  61. /* NOTE: some assembly code (in intr.s and contxt.s) makes
  62.  * assumptions about the offsets of sysstack, ctxt[0], systime,
  63.  * and usrtime.
  64.  */
  65.     long    sysstack;        /* must be first        */
  66.     CONTEXT    ctxt[PROC_CTXTS];    /* must be second        */
  67.  
  68.     long    magic;            /* validation for proc struct    */
  69.  
  70.     char    *base;            /* process base page        */
  71.     short    pid, ppid, pgrp;
  72.     short    ruid;            /* process real user id     */
  73.     short    rgid;            /* process real group id     */
  74.     short    euid, egid;        /* effective user and group ids */
  75.  
  76.     ushort    memflags;        /* e.g. malloc from alternate ram */
  77.     short    pri;            /* base process priority     */
  78.     short    wait_q;            /* current process queue    */
  79.     long    wait_cond;        /* condition we're waiting on    */
  80.                     /* (also return code from wait) */
  81.  
  82.     /* (all times are in milliseconds) */
  83.     ulong    systime;        /* time spent in kernel        */
  84.     ulong    usrtime;        /* time spent out of kernel    */
  85.     ulong    chldstime;        /* children's kernel time     */
  86.     ulong    chldutime;        /* children's user time        */
  87.  
  88.     ulong    maxmem;            /* max. amount of memory to use */
  89.     ulong    maxdata;        /* max. data region for process */
  90.     ulong    maxcore;        /* max. core memory for process */
  91.     ulong    maxcpu;            /* max. cpu time to use     */
  92.  
  93.     short    domain;            /* process domain (TOS or UNIX)    */
  94.  
  95.     short    curpri;            /* current process priority    */
  96. #define MIN_NICE -20
  97. #define MAX_NICE 20
  98. } PROC;
  99.  
  100. /* different process queues */
  101.  
  102. #define CURPROC_Q    0
  103. #define READY_Q        1
  104. #define WAIT_Q        2
  105. #define IO_Q        3
  106. #define ZOMBIE_Q    4
  107. #define TSR_Q        5
  108. #define STOP_Q        6
  109. #define SELECT_Q    7
  110.  
  111. #define NUM_QUEUES    8
  112.  
  113. struct status {
  114.     char mint;
  115.     char desc;
  116. }   proc_stat[NUM_QUEUES + 1] = {
  117.     CURPROC_Q,    'R',
  118.     READY_Q,    'R',
  119.     WAIT_Q,    'S',
  120.     IO_Q,    'S',
  121.     SELECT_Q,    'S',
  122.     STOP_Q,    'T',
  123.     ZOMBIE_Q,    'Z',
  124.     TSR_Q,    'X',
  125.     -1, '?'
  126. };                /* initialized from data in procfs.c */
  127.  
  128. void
  129. main(argc, argv)
  130.     int argc;
  131.     char **argv;
  132. {
  133.     DIR *dirp;
  134.     struct dirent *ent;
  135.     struct stat info;
  136.     int fd;
  137.     int fserror;
  138.     long place;
  139.     short pid,
  140.         ppid,
  141.         pri,
  142.         curpri;
  143.     char *s,
  144.     username[9];
  145.     struct status *statp;
  146.     BASEPAGE bpage;        /* process basepage read in here if possible */
  147.     PROC proc;            /* process info read in here */
  148.     long ptime;
  149.     long hour,
  150.         min,
  151.         sec,
  152.         frac;
  153.     struct passwd *pwent;
  154.  
  155.     if (chdir(PROCDIR) || !(dirp = opendir("."))) {
  156.     perror(PROCDIR);
  157.     return 1;
  158.     }
  159.  
  160.     printf("USER     PID PRI/CUR STAT SIZE   TIME   COMMAND\n");
  161.     username[8] = '\0';
  162.     
  163.     while (ent = readdir(dirp)) {
  164.     if ((fd = open(ent->d_name, 0)) < 0 || fstat(fd, &info))
  165.         goto next;
  166.  
  167.     /* Should really copy the name elsewhere. */
  168.     for (s = ent->d_name; *s && *s != '.'; s++);
  169.     *s = '\0';
  170.  
  171.     ioctl(fd, PPROCADDR, &place);
  172.     lseek(fd, place, 0);
  173.     read(fd, &proc, sizeof(proc));
  174.  
  175.     if (pwent = getpwuid(proc.ruid))
  176.         strncpy(username, pwent->pw_name, 8);
  177.     else
  178.         strcpy(username, "??user??");
  179.  
  180.     ptime = proc.systime + proc.usrtime;
  181.     hour = (ptime / 1000 / 60 / 60);
  182.     min = (ptime / 1000 / 60) % 60;
  183.     sec = (ptime / 1000) % 60;
  184.     frac = (ptime % 1000) / 10;    /* (never anything in .00x digit) */
  185.  
  186.     ioctl(fd, PBASEADDR, &place);
  187.     lseek(fd, place, 0);
  188.     read(fd, &bpage, sizeof(bpage));
  189.     if (*bpage.p_cmdlin)
  190.         *bpage.p_cmdlin = ' ';
  191.     close(fd);
  192.  
  193.     statp = proc_stat;    /* hunt down string referring to process
  194.                  * status */
  195.     while (statp->mint != proc.wait_q &&
  196.            statp->mint >= 0)
  197.         statp++;
  198.  
  199.     printf("%-8s %03d %3d/%3d %c %c  ", username, proc.pid,
  200.            proc.pri, proc.curpri, statp->desc,
  201.            proc.pri < 0 ? 'N' : proc.pri > 0 ? '<' : ' ');
  202.     if (info.st_size > 1000000L)
  203.         printf("%3ldM ", info.st_size / 1000000L);
  204.     else if (info.st_size > 1000L)
  205.         printf("%3ldk ", info.st_size / 1000L);
  206.     else
  207.         printf("%3ld  ", info.st_size);
  208.     if (hour)
  209.         printf("%02ld:%02ld:%02ld", hour, min, sec);
  210.     else
  211.         printf("%02ld:%02ld.%02ld", min, sec, frac);
  212.     printf(" %s%s\n", ent->d_name, bpage.p_cmdlin);
  213. next:
  214.     }
  215.     closedir(dirp);
  216.     endpwent();
  217.     return 0;
  218. }
  219.